package com.hqyj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hqyj.config.SmsConfig;
import com.hqyj.dao.PowerMapper;
import com.hqyj.dao.RolePowerMapper;
import com.hqyj.dao.UserRoleMapper;
import com.hqyj.pojo.*;
import com.hqyj.dao.UserMapper;
import com.hqyj.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author rock
 * @since 2022-09-30
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private PowerMapper powerMapper;

    @Resource
    private RolePowerMapper rolePowerMapper;

    //注入redis
    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    //注入邮件发送服务类
    @Autowired
    JavaMailSender javaMailSender;

    //获取邮件发送人邮箱
    @Value("${spring.mail.username}")
    private String fromEmail;

    //注入短信发送服务类
    @Autowired
    SmsClient smsClient;

    //注入腾讯配置类
    @Autowired
    SmsConfig smsConfig;

    @Override
    public User getUserInfoByName(String username, String password) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name",username).eq("user_pwd",password);
        return this.getOne(wrapper);
    }

    @Override
    public ResultVo userList(UserRoleVo userRoleVo) {
        //1.创建分页对象
        Page<UserRoleVo> page = new Page<>(userRoleVo.getPage(), userRoleVo.getRow());
        //查询分页
        List<UserRoleVo> list = userMapper.queryPage(page, userRoleVo);

        ResultVo rv = new ResultVo();
        if (list.size()==0){
            rv.setInfo("没有查询到数据");
            return rv;
        }
        HashMap<String, Object> map = new HashMap<>();
        //当前页集合
        map.put("list",list);
        //总页数
        map.put("totalPage",page.getPages());
        //总条数
        map.put("total",page.getTotal());
        rv.setInfo("查询成功");
        rv.setCode(200);
        rv.setData(map);
        return rv;
    }

    @Override
    public ResultVo userUpdate(UserRoleVo userRoleVo) {
        //修改用户信息
        User user = new User();
        user.setUserId(userRoleVo.getUserId());
        user.setUserName(userRoleVo.getUserName());
        user.setUserPwd(userRoleVo.getUserPwd());
        user.setUserEmail(userRoleVo.getUserEmail());
        user.setUserTel(userRoleVo.getUserTel());
        int userupdate = userMapper.updateById(user);
        //修改用户角色
        UserRole userRole = new UserRole();
        userRole.setUserId(userRoleVo.getUserId());
        if (userRoleVo.getRoleName().equals("admin")){
            userRole.setRoleId(1);
        }
        if (userRoleVo.getRoleName().equals("simple")){
            userRole.setRoleId(2);
        }
        UpdateWrapper<UserRole> wrapper = new UpdateWrapper<>();
        wrapper.eq("user_id",user.getUserId());
        int i = userRoleMapper.update(userRole,wrapper);
        if (i>0 && userupdate>0){
            ResultVo resultVo = new ResultVo();
            resultVo.setCode(200);
            resultVo.setInfo("修改成功");
            return resultVo;
        }else {
            ResultVo resultVo = new ResultVo();
            resultVo.setCode(500);
            resultVo.setInfo("修改失败");
            return resultVo;
        }
    }

    @Override
    public ResultVo userDelete(UserRoleVo userRoleVo) {
        //根据userId删除用户表中的数据
        int uresult = userMapper.deleteById(userRoleVo.getUserId());
        //根据userId删除user_role表中的数据
        int urresult = userRoleMapper.deleteById(userRoleVo.getUserId());
        if (uresult>0&&urresult>0){
            ResultVo resultVo = new ResultVo();
            resultVo.setCode(200);
            resultVo.setInfo("删除成功");
            return resultVo;
        }else {
            ResultVo resultVo = new ResultVo();
            resultVo.setCode(500);
            resultVo.setInfo("删除失败");
            return resultVo;
        }

    }

    //添加用户
    @Override
    public ResultVo UserRoleVo(UserRoleVo userRoleVo) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name",userRoleVo.getUserName());
        User userCheck = userMapper.selectOne(wrapper);
        if (Objects.isNull(userCheck)){ //判断当前用户名是否已被使用
            //添加用户信息
            User user = new User();
            user.setUserName(userRoleVo.getUserName());
            user.setUserPwd(userRoleVo.getUserPwd());
            user.setUserTel(userRoleVo.getUserTel());
            user.setUserEmail(userRoleVo.getUserEmail());
            int userInsert = userMapper.insert(user);

            //查询出添加后的用户的用户id
            QueryWrapper<User> wrapperadd = new QueryWrapper<>();
            wrapperadd.eq("user_name",userRoleVo.getUserName());
            User useradd = userMapper.selectOne(wrapperadd);
            //添加用户角色信息
            UserRole userRole = new UserRole();
            userRole.setUserId(useradd.getUserId());
            if (userRoleVo.getRoleName().equals("admin")){
                userRole.setRoleId(1);
            }
            if (userRoleVo.getRoleName().equals("simple")){
                userRole.setRoleId(2);
            }
            int urInsert = userRoleMapper.insert(userRole);

            if (userInsert > 0 && urInsert >0){
                ResultVo resultVo = new ResultVo();
                resultVo.setCode(200);
                resultVo.setInfo("添加成功");
                return resultVo;
            }else if (userInsert > 0 && urInsert <= 0){
                ResultVo resultVo = new ResultVo();
                resultVo.setCode(500);
                resultVo.setInfo("角色添加失败");
                return resultVo;
            }else if (userInsert <= 0 && urInsert > 0){
                ResultVo resultVo = new ResultVo();
                resultVo.setCode(500);
                resultVo.setInfo("用户信息添加失败");
                return resultVo;
            }else {
                ResultVo resultVo = new ResultVo();
                resultVo.setCode(500);
                resultVo.setInfo("添加失败");
                return resultVo;
            }
        }else {
            ResultVo resultVo = new ResultVo();
            resultVo.setCode(200);
            resultVo.setInfo("对不起,用户名已被使用");
            return resultVo;
        }
    }

    //发送邮件验证码
    @Override
    public ResultVo sendEmailCode(String userEmail) {
        ResultVo resultVo = new ResultVo();
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_email",userEmail);
        User user = userMapper.selectOne(wrapper);
        if (Objects.isNull(user)){
            resultVo.setCode(500);
            resultVo.setInfo("该用户不存在");
            return resultVo;
        }else {
            try {
                //创建信封对象
                SimpleMailMessage message = new SimpleMailMessage();
                //收件人
                message.setTo(userEmail);
                //发件人
                message.setFrom(fromEmail);
                //邮件标题
                message.setSubject("xxx公司验证码");
                //邮件正文
                Random random = new Random();
                String code = random.nextInt(10000)+"";
                message.setText("你的验证码是："+code);
                //发送邮件
                javaMailSender.send(message);
                //存入redis缓存中一分钟
                String key = "code:"+userEmail;
                redisTemplate.opsForValue().set(key,code,1, TimeUnit.MINUTES);
                resultVo.setCode(200);
                resultVo.setInfo("发送成功");
                return resultVo;
            }catch (Exception e){
                e.printStackTrace();
                resultVo.setInfo("发送失败");
                return resultVo;
            }
        }
    }

    //邮件登录
    @Override
    public ResultVo emailLogin(String userEmail, String code) {
        ResultVo resultVo = new ResultVo();
        String key = "code:"+userEmail;
        Object o = redisTemplate.opsForValue().get(key);
        if (o==null){
            resultVo.setCode(500);
            resultVo.setInfo("已超过一分钟,验证码失效");
            return resultVo;
        }else {
            if (o.equals(code)){
                QueryWrapper<User> wrapper = new QueryWrapper<>();
                //根据邮件查出用户信息
                wrapper.eq("user_email",userEmail);
                User user = userMapper.selectOne(wrapper);
                //把用户信息存入redis
                String userkey = "user:"+userEmail;
                redisTemplate.opsForValue().set(userkey,user);
                //把user信息存入服务端的session内
                SecurityUtils.getSubject().getSession().setAttribute("userkey",user);
                resultVo.setCode(200);
                resultVo.setInfo("登录成功");
                resultVo.setData(user);
                return resultVo;
            }else {
                resultVo.setCode(500);
                resultVo.setInfo("验证码不正确");
                return resultVo;
            }
        }
    }

    //电话发送短信验证码
    @Override
    public ResultVo sendSmsCode(String userTel) {
        ResultVo resultVo = new ResultVo();
        //判断该电话是否有用户信息
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_tel",userTel);
        User user = userMapper.selectOne(wrapper);
        if (Objects.isNull(user)){
            resultVo.setCode(500);
            resultVo.setInfo("该电话没有注册用户，请先注册用户");
            return resultVo;
        }else {
            //创建短信内容对象
            SendSmsRequest request = new SendSmsRequest();
            //接受人手机号
            String phone[] = {userTel};
            request.setPhoneNumberSet(phone);
            //短信模板
            request.setTemplateId(smsConfig.getSmsTemplId());
            request.setSmsSdkAppId(smsConfig.getSmsSdk());
            request.setSignName(smsConfig.getSmsName());
            //短信验证码
            Random random = new Random();
            String code = random.nextInt(10000)+"";
            String c[] = {code};
            request.setTemplateParamSet(c);
            //发送短信
            try {
                SendSmsResponse res = smsClient.SendSms(request);
                //把json格式字符串转换为map类型
                ObjectMapper mapper = new ObjectMapper();
                try {
                    System.out.println(SendSmsResponse.toJsonString(res));
                    Map<String,Object> map = mapper.readValue(SendSmsResponse.toJsonString(res), Map.class);
                    List<HashMap<String,Object>> list = (List<HashMap<String, Object>>) map.get("SendStatusSet");
                    System.out.println(list.get(0));
                    if (list.get(0).get("Code").equals("Ok")){
                        //将验证码存入redis一分钟
                        String key = "msm:"+userTel;
                        redisTemplate.opsForValue().set(key,code,1,TimeUnit.MINUTES);
                        resultVo.setCode(200);
                        resultVo.setInfo("发送成功");
                        return resultVo;
                    }
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            } catch (TencentCloudSDKException e) {
                e.printStackTrace();
            }
            resultVo.setCode(500);
            resultVo.setInfo("发送失败");
            return resultVo;
        }
    }

    //短信登录
    @Override
    public ResultVo smsLogin(String userTel, String code) {
        ResultVo resultVo = new ResultVo();
        String key = "msm:"+userTel;
        Object o = redisTemplate.opsForValue().get(key);
        if (o==null){
            resultVo.setCode(500);
            resultVo.setInfo("已超过一分钟,短信验证码已失效");
            return resultVo;
        }else {
            if (code.equals(o)){
                QueryWrapper<User> wrapper = new QueryWrapper<>();
                //根据邮件查出用户信息
                wrapper.eq("user_tel",userTel);
                User user = userMapper.selectOne(wrapper);
                //把用户信息存入redis
                String userkey = "user:"+userTel;
                redisTemplate.opsForValue().set(userkey,user);
                //把user信息存入服务端的session内
                SecurityUtils.getSubject().getSession().setAttribute("userkey",user);
                resultVo.setCode(200);
                resultVo.setInfo("登录成功");
                resultVo.setData(user);
                return resultVo;
            }else {
                resultVo.setCode(500);
                resultVo.setInfo("验证码不正确");
                return resultVo;
            }
        }
    }

    //根据用户名查询权限
    @Override
    public ResultVo queryByName(String name) {
        ResultVo resultVo = new ResultVo();
        List<MyNode> list = powerMapper.queryByName(name);
        //封装list为树形集合
        LinkedList<MyNode> listParent = new LinkedList<>();
        if (list.size()==0){
            resultVo.setCode(500);
            resultVo.setInfo("该用户没有权限");
            return resultVo;
        }
        if (list.size()!=0){
            //遍历出父节点
            for (MyNode n:list){
                if (n.getParentId()==0){ //确定一级菜单
                    //创建一级菜单子集合
                    List<MyNode> listChildren = new LinkedList<>();
                    for (MyNode nn:list){
                        if (nn.getParentId()==n.getNodeId()){
                            listChildren.add(nn);
                        }
                    }
                    //添加子菜单
                    n.setChildren(listChildren);
                    listParent.add(n);
                }
            }
            resultVo.setCode(200);
            resultVo.setData(listParent);
            return resultVo;
        }
        resultVo.setInfo("未知错误");
        return resultVo;
    }

    //修改密码发送邮箱
    @Override
    public ResultVo pwdSendEmailCode(RuleForm ruleForm) {
        ResultVo resultVo = new ResultVo();
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_email",ruleForm.getEmail());
        User user = userMapper.selectOne(wrapper);
        if (Objects.isNull(user)){
            resultVo.setCode(500);
            resultVo.setInfo("该用户不存在");
            return resultVo;
        }else {
            try {
                //创建信封对象
                SimpleMailMessage message = new SimpleMailMessage();
                //收件人
                message.setTo(ruleForm.getEmail());
                //发件人
                message.setFrom(fromEmail);
                //邮件标题
                message.setSubject("xxx公司验证码");
                //邮件正文
                Random random = new Random();
                String code = random.nextInt(10000)+"";
                message.setText("你的验证码是："+code);
                //发送邮件
                javaMailSender.send(message);
                //存入redis缓存中一分钟
                String key = "code:"+ruleForm.getEmail();
                redisTemplate.opsForValue().set(key,code,1, TimeUnit.MINUTES);
                resultVo.setCode(200);
                resultVo.setInfo("发送成功");
                return resultVo;
            }catch (Exception e){
                e.printStackTrace();
                resultVo.setInfo("发送失败");
                return resultVo;
            }
        }
    }

    @Override
    public ResultVo updatePwd(RuleForm ruleForm) {
        ResultVo resultVo = new ResultVo();
        String key = "code:"+ruleForm.getEmail();
        Object o = redisTemplate.opsForValue().get(key);
        if (o==null){
            resultVo.setCode(500);
            resultVo.setInfo("已超过一分钟,验证码失效");
            return resultVo;
        }else {
            if (o.equals(ruleForm.getCode())){
                UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
                User user1 = new User();
                user1.setUserPwd(ruleForm.getPass());
                //根据邮件修改用户密码
                updateWrapper.eq("user_email",ruleForm.getEmail());
                userMapper.update(user1,updateWrapper);

                resultVo.setCode(200);
                resultVo.setInfo("密码修改成功");
                return resultVo;
            }else {
                resultVo.setCode(500);
                resultVo.setInfo("验证码不正确");
                return resultVo;
            }
        }
    }

    @Override
    public ResultVo powerInfo(PowerList powerList) {
        //1.创建分页对象
        Page<PowerList> page = new Page<>(powerList.getPage(), powerList.getRow());
        //查询分页
        List<PowerList> list = userMapper.queryPowerList(page, powerList);

        ResultVo rv = new ResultVo();
        if (list.size()==0){
            rv.setInfo("没有查询到数据");
            return rv;
        }
        HashMap<String, Object> map = new HashMap<>();
        //当前页集合
        map.put("list",list);
        //总页数
        map.put("totalPage",page.getPages());
        //总条数
        map.put("total",page.getTotal());
        rv.setInfo("查询成功");
        rv.setCode(200);
        rv.setData(map);
        return rv;
    }

    @Override
    public ResultVo powerUpdate(String str, String roleId) {
        ResultVo resultVo = new ResultVo();
        //将str转换成数组
        String arr[] = str.split(",");
        //先根据roleId删除
        QueryWrapper<RolePower> delWrapper = new QueryWrapper<>();
        delWrapper.in("role_id",roleId);
        rolePowerMapper.delete(delWrapper);
        //添加powerId
        RolePower rolePower = new RolePower();
        Integer rId = Integer.valueOf(roleId);
        //遍历所有的powerId,进行修改
        for (int i = 0; i < arr.length; i++) {
            rolePower.setRoleId(rId);
            rolePower.setPowerId(Integer.valueOf(arr[i]));
            int result = rolePowerMapper.insert(rolePower);
            if (result<=0){
                resultVo.setCode(500);
                resultVo.setInfo("修改出错");
                return resultVo;
            }
        }
        resultVo.setCode(200);
        resultVo.setInfo("修改成功");
        return resultVo;
    }


}
